package com.innovation.chengzhangriji.database;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.text.TextUtils;
import android.util.Log;

import com.innovation.chengzhangriji.Baby;
import com.innovation.chengzhangriji.BabyAndParent;
import com.innovation.chengzhangriji.BabyAndParentDao;
import com.innovation.chengzhangriji.BabyDao;
import com.innovation.chengzhangriji.Config;
import com.innovation.chengzhangriji.DaoMaster;
import com.innovation.chengzhangriji.DaoSession;
import com.innovation.chengzhangriji.Discover;
import com.innovation.chengzhangriji.DiscoverDao;
import com.innovation.chengzhangriji.DiscoverPhoto;
import com.innovation.chengzhangriji.DiscoverPhotoDao;
import com.innovation.chengzhangriji.DiscoverSaveComment;
import com.innovation.chengzhangriji.DiscoverSaveCommentDao;
import com.innovation.chengzhangriji.Message;
import com.innovation.chengzhangriji.MessageDao;
import com.innovation.chengzhangriji.Parent;
import com.innovation.chengzhangriji.ParentDao;
import com.innovation.chengzhangriji.PublicMilestone;
import com.innovation.chengzhangriji.PublicMilestoneDao;
import com.innovation.chengzhangriji.PublicPhotoTheme;
import com.innovation.chengzhangriji.PublicPhotoThemeDao;
import com.innovation.chengzhangriji.Timeline;
import com.innovation.chengzhangriji.TimelineAudioUrl;
import com.innovation.chengzhangriji.TimelineAudioUrlDao;
import com.innovation.chengzhangriji.TimelineDao;
import com.innovation.chengzhangriji.TimelineDelete;
import com.innovation.chengzhangriji.TimelineDeleteDao;
import com.innovation.chengzhangriji.TimelineLastServerTime;
import com.innovation.chengzhangriji.TimelineLastServerTimeDao;
import com.innovation.chengzhangriji.TimelineMilestone;
import com.innovation.chengzhangriji.TimelineMilestoneDao;
import com.innovation.chengzhangriji.TimelinePhoto;
import com.innovation.chengzhangriji.TimelinePhotoDao;
import com.innovation.chengzhangriji.TimelinePhotoUrl;
import com.innovation.chengzhangriji.TimelinePhotoUrlDao;
import com.innovation.chengzhangriji.TimelineServerTime;
import com.innovation.chengzhangriji.TimelineServerTimeDao;
import com.innovation.chengzhangriji.TimelineText;
import com.innovation.chengzhangriji.TimelineTextDao;
import com.innovation.chengzhangriji.TimelineVideoScreenshotUrl;
import com.innovation.chengzhangriji.TimelineVideoScreenshotUrlDao;
import com.innovation.chengzhangriji.TimelineVideoUrl;
import com.innovation.chengzhangriji.TimelineVideoUrlDao;
import com.innovation.chengzhangriji.http.Auth;
import com.innovation.chengzhangriji.http.BabyResponse;
import com.innovation.chengzhangriji.http.DataResponse;
import com.innovation.chengzhangriji.http.DiscoverCommentResponse;
import com.innovation.chengzhangriji.http.DiscoverContentResponse;
import com.innovation.chengzhangriji.http.DiscoverLikeResponse;
import com.innovation.chengzhangriji.http.MilestoneGetResponse;
import com.innovation.chengzhangriji.http.TypeDataResponse;
import com.innovation.chengzhangriji.preferences.LoginInfo;
import com.innovation.chengzhangriji.ui.model.CommentModel;
import com.innovation.chengzhangriji.ui.model.DTModel;
import com.innovation.chengzhangriji.ui.model.DiscoverModel;
import com.innovation.chengzhangriji.ui.task.ReadImageSizeTask;
import com.innovation.chengzhangriji.util.Size;
import com.orhanobut.logger.Logger;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import de.greenrobot.dao.query.QueryBuilder;

public class DatabaseManager {

    private volatile static DatabaseManager instance;

    private DaoMaster.DevOpenHelper mHelper;

    private SQLiteDatabase database;

    private DaoMaster daoMaster;

    private DaoSession daoSession;

    private DatabaseManager(Context context) {
        mHelper = new DaoMaster.DevOpenHelper(context, Config.DB_NAME, null);
    }

    public static DatabaseManager getInstance(Context context) {
        if (instance == null) {
            synchronized (DatabaseManager.class) {
                if (instance == null) {
                    instance = new DatabaseManager(context);
                }
            }
        }
        return instance;
    }

    public void closeDbConnections() {
        if (daoSession != null) {
            daoSession.clear();
            daoSession = null;
        }
        if (database != null && database.isOpen()) {
            database.close();
        }
        if (mHelper != null) {
            mHelper.close();
            mHelper = null;
        }
        if (instance != null) {
            instance = null;
        }
    }

    /**
     * 插入或更新登录标识与对应的宝贝标识
     */
    public void insertOrReplaceInTxBabyAndParent(String parentID, Auth[] auth, int... babyIDArray) {
        openWritableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        List<BabyAndParent> babyAndParentDelete = babyAndParentDao.queryBuilder().where(BabyAndParentDao.Properties.ParentID.eq(parentID)).list();
        babyAndParentDao.deleteInTx(babyAndParentDelete);
        int length = babyIDArray.length;
        BabyAndParent[] babyAndParentArray = new BabyAndParent[length];
        for (int i = 0; i < length; i++) {
            BabyAndParent babyAndParent = babyAndParentDao.queryBuilder().where(BabyAndParentDao.Properties.ParentID.eq(parentID), BabyAndParentDao.Properties.BabyID.eq(babyIDArray[i])).unique();
            if (babyAndParent != null) {
                babyAndParentArray[i] = babyAndParent;
                babyAndParentArray[i].setRole(auth[i].getRole());
                babyAndParentArray[i].setPermission(auth[i].getPermission());
                babyAndParentArray[i].setRange(auth[i].getRange());
                babyAndParentArray[i].setNumber(i);
            } else {
                babyAndParentArray[i] = new BabyAndParent();
                babyAndParentArray[i].setParentID(parentID);
                babyAndParentArray[i].setBabyID(babyIDArray[i]);
                babyAndParentArray[i].setRole(auth[i].getRole());
                babyAndParentArray[i].setPermission(auth[i].getPermission());
                babyAndParentArray[i].setRange(auth[i].getRange());
                babyAndParentArray[i].setNumber(i);
            }
        }
        babyAndParentDao.insertOrReplaceInTx(babyAndParentArray);
    }

    /**
     * 插入或更新宝贝信息
     */
    public void insertOrReplaceInTxBaby(BabyResponse... data) {
        openWritableDb();
        BabyDao babyDao = daoSession.getBabyDao();
        int length = data.length;
        Baby[] babyArray = new Baby[length];
        for (int i = 0; i < length; i++) {
            Baby baby = babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(data[i].getId())).unique();
            if (baby != null) {
                babyArray[i] = baby;
            } else {
                babyArray[i] = new Baby();
            }
            babyArray[i].setNoteName(data[i].getNoteName());
            babyArray[i].setBabyID(data[i].getId());
            babyArray[i].setName(data[i].getName());
            babyArray[i].setState(data[i].getState());
            babyArray[i].setParentName(data[i].getParentName());
            babyArray[i].setGender(data[i].getGender());
            babyArray[i].setImageUrl(data[i].getImageUrl());
            babyArray[i].setBirthday(data[i].getBirthday());
            babyArray[i].setLastDate(data[i].getLastDate());
            babyArray[i].setDueDate(data[i].getDueDate());
            babyArray[i].setUpdateTime(data[i].getUpdateTime());
        }
        babyDao.insertOrReplaceInTx(babyArray);
    }

    /**
     * 删除单个宝贝信息
     */
    public void deleteBaby(int babyId) {
        openWritableDb();
        // 删除宝宝信息
        BabyDao babyDao = daoSession.getBabyDao();
        babyDao.deleteInTx(babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(babyId)).list());
        // 删除所有关注人信息
        deleteAllParents(babyId);
        // 删除所有宝宝关系
        BabyAndParentDao parentDao = daoSession.getBabyAndParentDao();
        parentDao.deleteInTx(parentDao.queryBuilder().where(BabyAndParentDao.Properties.BabyID.eq(babyId)).list());

        // 删除日记信息
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> discovers = discoverDao.queryBuilder().where(DiscoverDao.Properties.BabyID.eq(babyId)).list();
        for(Discover discover : discovers) {
            discoverDao.deleteInTx(discover);
            // 删除评论信息
            DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
            commentDao.deleteInTx(commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.DiaryID.eq(discover.getDiaryID())).list());
            // 删除所有待上传信息
            deleteUnSyncTimeline(discover.getDiaryID());
        }
    }

    /**
     * 删除所有(除了Timeline，离线评论)
     */
    public void deleteAll() {
        openWritableDb();
        // 删除宝宝信息
        BabyDao babyDao = daoSession.getBabyDao();
        babyDao.deleteAll();
        // 删除拉取戳
        TimelineLastServerTimeDao timelineLastServerTimeDao = daoSession.getTimelineLastServerTimeDao();
        timelineLastServerTimeDao.deleteAll();
        TimelineServerTimeDao timelineServerTimeDao = daoSession.getTimelineServerTimeDao();
        timelineServerTimeDao.deleteAll();
        // 删除宝宝与关注人信息
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        babyAndParentDao.deleteAll();
        // 删除宝宝信息
        ParentDao parentDao = daoSession.getParentDao();
        parentDao.deleteAll();
        // 删除日记信息
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        discoverDao.deleteAll();
        // 删除非离线的所有评论信息
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        commentDao.deleteInTx(commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.IsLocal.eq(false)).list());
    }

    /**
     * 删除所有的关注人信息
     */
    public void deleteAllParents(int babyId) {
        openWritableDb();
        ParentDao parentDao = daoSession.getParentDao();
        parentDao.deleteInTx(parentDao.queryBuilder().where(ParentDao.Properties.BabyId.eq(babyId)).list());
    }

    /**
     * 插入或更新关注人信息
     */
    public void insertOrReplaceInTxParent(Parent... parents) {
        openWritableDb();
        ParentDao parentDao = daoSession.getParentDao();
        int length = parents.length;
        Parent[] parentsArray = new Parent[length];
        for (int i = 0; i < length; i++) {
            Parent parent = parentDao.queryBuilder().where(
                    ParentDao.Properties.BabyId.eq(parents[i].getBabyId()),
                    ParentDao.Properties.ParentId.eq(parents[i].getParentId())).unique();
            if (parent != null) {
                parentsArray[i] = parent;
            } else {
                parentsArray[i] = new Parent();
            }
            parentsArray[i].setBabyId(parents[i].getBabyId());
            parentsArray[i].setType(parents[i].getType());
            parentsArray[i].setParentId(parents[i].getParentId());
            parentsArray[i].setUser(parents[i].getUser());
            parentsArray[i].setName(parents[i].getName());
            parentsArray[i].setPhone(parents[i].getPhone());
            parentsArray[i].setServerTS(parents[i].getServerTS());
            parentsArray[i].setMessage(parents[i].getMessage());
            parentsArray[i].setPath(parents[i].getPath());
            parentsArray[i].setNickName(parents[i].getNickName());
            parentsArray[i].setRole(parents[i].getRole());
            parentsArray[i].setPermission(parents[i].getPermission());
            parentsArray[i].setRange(parents[i].getRange());
        }
        parentDao.insertOrReplaceInTx(parentsArray);
    }

    public Parent[] queryParent(int babyId) {
        openReadableDb();
        ParentDao parentDao = daoSession.getParentDao();
        List<Parent> list = parentDao.queryBuilder().where(
                ParentDao.Properties.BabyId.eq(babyId)).list();
        if (list == null || list.size() == 0) {
            return null;
        }
        return list.toArray(new Parent[list.size()]);
    }

    public void updateAdmin(String userId, int babyId) {
        openWritableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        BabyAndParent babyAndParent = babyAndParentDao.queryBuilder().where(
                BabyAndParentDao.Properties.ParentID.eq(userId),
                BabyAndParentDao.Properties.BabyID.eq(babyId)).unique();
        babyAndParent.setRole(1);
        babyAndParentDao.update(babyAndParent);
    }

    /**
     * 更新宝贝信息
     */
    public void updateBaby(Baby baby) {
        openWritableDb();
        BabyDao babyDao = daoSession.getBabyDao();
        Baby babyOld = babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(baby.getBabyID())).unique();
        babyOld.setNoteName(baby.getNoteName());
        babyOld.setBabyID(baby.getBabyID());
        babyOld.setName(baby.getName());
        babyOld.setState(baby.getState());
        babyOld.setParentName(baby.getParentName());
        babyOld.setGender(baby.getGender());
        babyOld.setImageUrl(baby.getImageUrl());
        babyOld.setBirthday(baby.getBirthday());
        babyOld.setLastDate(baby.getLastDate());
        babyOld.setDueDate(baby.getDueDate());
        babyOld.setUpdateTime(baby.getUpdateTime());
        babyDao.update(babyOld);
    }

    /**
     * 查询服务器同步时间
     */
    public long querySyncTS(int babyID) {
        openReadableDb();
        TimelineServerTimeDao timelineServerTimeDao = daoSession.getTimelineServerTimeDao();
        TimelineServerTime timelineServerTime = timelineServerTimeDao.queryBuilder()
                .where(TimelineServerTimeDao.Properties.BabyID.eq(babyID)).unique();
        if (timelineServerTime == null) {
            return 0;
        }
        return timelineServerTime.getSyncTS();
    }

    /**
     * 查询服务器未同步时间戳
     */
    public TimelineLastServerTime queryLastServerTime(int babyID) {
        openReadableDb();
        TimelineLastServerTimeDao timelineLastServerTimeDao = daoSession.getTimelineLastServerTimeDao();
        TimelineLastServerTime timelineLastServerTime = timelineLastServerTimeDao.queryBuilder()
                .where(
                        TimelineLastServerTimeDao.Properties.BabyID.eq(babyID),
                        TimelineLastServerTimeDao.Properties.LastNumber.notEq(0))
                .orderDesc(TimelineLastServerTimeDao.Properties.SyncTS)
                .limit(1).unique();
        if (timelineLastServerTime != null) {
            return timelineLastServerTime;
        }
        return null;
    }

    /**
     * 查询服务器未同步时间戳
     */
    public TimelineLastServerTime queryLastServerTime(int babyID, String uuid) {
        openReadableDb();
        TimelineLastServerTimeDao timelineLastServerTimeDao = daoSession.getTimelineLastServerTimeDao();
        TimelineLastServerTime timelineLastServerTime = timelineLastServerTimeDao.queryBuilder()
                .where(
                        TimelineLastServerTimeDao.Properties.BabyID.eq(babyID),
                        TimelineLastServerTimeDao.Properties.Uuid.eq(uuid),
                        TimelineLastServerTimeDao.Properties.LastNumber.notEq(0))
                .unique();
        if (timelineLastServerTime != null) {
            return timelineLastServerTime;
        }
        return null;
    }

    /**
     * 插入或更新服务器同步时间
     */
    public void insertOrReplaceServerTime(int babyID, long serverTime) {
        openWritableDb();
        TimelineServerTimeDao timelineServerTimeDao = daoSession.getTimelineServerTimeDao();
        TimelineServerTime timelineServerTime = timelineServerTimeDao.queryBuilder().where(TimelineServerTimeDao.Properties.BabyID.eq(babyID)).unique();
        if (timelineServerTime == null) {
            timelineServerTime = new TimelineServerTime();
        }
        timelineServerTime.setBabyID(babyID);
        timelineServerTime.setSyncTS(serverTime);
        timelineServerTimeDao.insertOrReplace(timelineServerTime);
    }

    /**
     * 插入或更新服务器未同步时间戳和未同步数量
     */
    public void insertOrReplaceLastServerTime(int babyID, String uuid, long serverTime, long lastServerTime, int lastNumber) {
        openWritableDb();
        TimelineLastServerTimeDao timelineLastServerTimeDao = daoSession.getTimelineLastServerTimeDao();
        TimelineLastServerTime timelineLastServerTime = timelineLastServerTimeDao.queryBuilder()
                .where(
                        TimelineLastServerTimeDao.Properties.BabyID.eq(babyID),
                        TimelineLastServerTimeDao.Properties.SyncTS.eq(serverTime))
                .unique();
        if (timelineLastServerTime == null) {
            timelineLastServerTime = new TimelineLastServerTime();
        }
        timelineLastServerTime.setBabyID(babyID);
        timelineLastServerTime.setUuid(uuid);
        timelineLastServerTime.setSyncTS(serverTime);
        timelineLastServerTime.setCreateTS(lastServerTime);
        timelineLastServerTime.setLastNumber(lastNumber);
        timelineLastServerTimeDao.insertOrReplace(timelineLastServerTime);
    }

    /**
     * 插入或更新由服务器获得的时间轴.
     */
    public void insertOrReplaceInTxTimelineByServer(int babyID, DataResponse data) {
        openWritableDb();
        int length = data.getData().length;
        if (length == 0) {
            return;
        }
        /*DaoSession*/
        TimelineDao timelineDao = daoSession.getTimelineDao();
        TimelineTextDao timelineTextDao = daoSession.getTimelineTextDao();
        TimelinePhotoDao timelinePhotoDao = daoSession.getTimelinePhotoDao();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineMilestoneDao timelineMilestoneDao = daoSession.getTimelineMilestoneDao();
        /*ArrayList*/
        Timeline[] timelineArray = new Timeline[length];
        ArrayList<TimelineText> textArrayList = new ArrayList<TimelineText>();
        ArrayList<TimelinePhoto> photoArrayList = new ArrayList<TimelinePhoto>();
        ArrayList<TimelinePhotoUrl> photoUrlArrayList = new ArrayList<TimelinePhotoUrl>();
        ArrayList<TimelineAudioUrl> audioUrlArrayList = new ArrayList<TimelineAudioUrl>();
        ArrayList<TimelineVideoScreenshotUrl> videoScreenshotUrlArrayList = new ArrayList<TimelineVideoScreenshotUrl>();
        ArrayList<TimelineVideoUrl> videoUrlArrayList = new ArrayList<TimelineVideoUrl>();
        ArrayList<TimelineMilestone> milestoneArrayList = new ArrayList<TimelineMilestone>();

        for (int i = 0; i < length; i++) {
            String uuid = data.getData()[i].getUuid();
            String userID = data.getData()[i].getUserID();
            String role = data.getData()[i].getRole();
            long createTS = data.getData()[i].getCreateTS();
            long changeTS = data.getData()[i].getChangeTS();
            int state = data.getData()[i].getState();
            int isDelete = 0;
            int type = data.getData()[i].getType();
            int babyState = data.getData()[i].getBabyState();
            Logger.d("得到的类型" + type);
            if (!TextUtils.isEmpty(data.getData()[i].getMilestone())) {
                type = TypeDataResponse.TYPE_MILESTONE;
            }
            // 判断是否已经有该条记录
            boolean newTimeline = false;
            timelineArray[i] = timelineDao.queryBuilder().
                    where(
                            TimelineDao.Properties.Uuid.isNotNull(),
                            TimelineDao.Properties.Uuid.eq(uuid)).unique();
            if (timelineArray[i] == null) {
                Logger.d("新的");
                timelineArray[i] = new Timeline();
                newTimeline = true;
            } else {
                Logger.d("已经存在");
                newTimeline = false;
            }
            timelineArray[i].setUuid(uuid);
            timelineArray[i].setBabyID(babyID);
            timelineArray[i].setUserID(userID);
            timelineArray[i].setRole(role);
            timelineArray[i].setState(babyState);
            timelineArray[i].setCreateTS(createTS);
            timelineArray[i].setChangeTS(changeTS);
            // 无论是服务器端还是本地客户端,只要标识该条数据删除,那么就删除了该条数据.
            if (timelineArray[i].getIsDelete() != null && timelineArray[i].getIsDelete() == 1 || state == 0) {
                isDelete = 1;
            } else {
                isDelete = 0;
            }
            timelineArray[i].setIsDelete(isDelete);
            timelineArray[i].setIsRemoteDelete(isDelete);
            timelineArray[i].setIsRemoteExist(1);

            if (newTimeline) {
                timelineArray[i].setIsLocalExist(0);
            } else {
                timelineArray[i].setIsLocalExist(1);
            }

            switch (type) {
                case TypeDataResponse.TYPE_TEXT:
                    timelineArray[i].setIsLocalExist(1);
                    break;
                case TypeDataResponse.TYPE_MILESTONE:
                    timelineArray[i].setIsLocalExist(1);
                    break;
            }

            timelineArray[i].setIsSyncError(0);
            timelineArray[i].setIsUploadError(0);
            timelineArray[i].setType(type);

            // 不是新数据
            if (!newTimeline) {
                continue;
            }

            switch (type) {
                case TypeDataResponse.TYPE_TEXT:
                    Logger.d("TYPE_TEXT");
                    String text = data.getData()[i].getText();
                    insertOrReplaceInTxTimelineTextByServer(timelineTextDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, text, textArrayList);
                    break;
                case TypeDataResponse.TYPE_PHOTO:
                    Logger.d("TYPE_PHOTO");
                    String photoText = data.getData()[i].getText();
                    String photoTheme = data.getData()[i].getTheme();
                    insertOrReplaceInTxTimelinePhotoByServer(timelinePhotoDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, photoText, photoTheme, photoArrayList);
                    int count = data.getData()[i].getPhotoUrls().length;
                    String[] photoUrls = new String[count];
                    System.arraycopy(data.getData()[i].getPhotoUrls(), 0, photoUrls, 0, count);
                    insertOrReplaceInTxTimelinePhotoUrlByServer(timelinePhotoUrlDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, count, photoUrls, photoUrlArrayList);
                    break;
                case TypeDataResponse.TYPE_AUDIO:
                    Logger.d("TYPE_AUDIO");
                    int audioLength = data.getData()[i].getLength();
                    String audioUrl = data.getData()[i].getAudioUrl();
                    insertOrReplaceInTxTimelineAudioUrlByServer(timelineAudioUrlDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, audioLength, audioUrl, audioUrlArrayList);
                    break;
                case TypeDataResponse.TYPE_VIDEO:
                    Logger.d("TYPE_VIDEO");
                    String screenshotUrl = data.getData()[i].getScreenshotUrl();
                    insertOrReplaceInTxTimelineVideoScreenshotUrlByServer(timelineVideoScreenshotUrlDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, screenshotUrl, videoScreenshotUrlArrayList);
                    String videoUrl = data.getData()[i].getVideoUrl();
                    int videoLength = data.getData()[i].getLength();
                    insertOrReplaceInTxTimelineVideoUrlByServer(timelineVideoUrlDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, videoLength, videoUrl, videoUrlArrayList);
                    break;
                case TypeDataResponse.TYPE_MILESTONE:
                    Logger.d("TYPE_MILESTONE");
                    String milestone = data.getData()[i].getMilestone();
                    insertOrReplaceInTxTimelineMilestoneByServer(timelineMilestoneDao, uuid, babyID, userID, role, babyState, createTS, changeTS, isDelete, milestone, milestoneArrayList);
                    break;
            }
        }
        timelineDao.insertOrReplaceInTx(timelineArray);
        timelineTextDao.insertOrReplaceInTx(textArrayList);
        timelinePhotoDao.insertOrReplaceInTx(photoArrayList);
        timelinePhotoUrlDao.insertOrReplaceInTx(photoUrlArrayList);
        timelineAudioUrlDao.insertOrReplaceInTx(audioUrlArrayList);
        timelineVideoScreenshotUrlDao.insertOrReplaceInTx(videoScreenshotUrlArrayList);
        timelineVideoUrlDao.insertOrReplaceInTx(videoUrlArrayList);
        timelineMilestoneDao.insertOrReplaceInTx(milestoneArrayList);
    }

    private void insertOrReplaceInTxTimelineTextByServer(TimelineTextDao timelineTextDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, String text, ArrayList<TimelineText> textArrayList) {
        TimelineText timelineText = timelineTextDao.queryBuilder().where(TimelineTextDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineText == null) {
            timelineText = new TimelineText();
        }
        timelineText.setUuid(uuid);
        timelineText.setBabyID(babyID);
        timelineText.setUserID(userID);
        timelineText.setRole(role);
        timelineText.setState(state);
        timelineText.setCreateTS(createTS);
        timelineText.setChangeTS(changeTS);
        timelineText.setIsDelete(isDelete);
        timelineText.setIsRemoteDelete(isDelete);
        timelineText.setText(text);
        textArrayList.add(timelineText);
    }

    private void insertOrReplaceInTxTimelinePhotoByServer(TimelinePhotoDao timelinePhotoDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, String text, String theme, ArrayList<TimelinePhoto> photoArrayList) {
        TimelinePhoto timelinePhoto = timelinePhotoDao.queryBuilder().where(TimelinePhotoDao.Properties.Uuid.eq(uuid)).unique();
        if (timelinePhoto == null) {
            timelinePhoto = new TimelinePhoto();
        }
        timelinePhoto.setUuid(uuid);
        timelinePhoto.setBabyID(babyID);
        timelinePhoto.setUserID(userID);
        timelinePhoto.setRole(role);
        timelinePhoto.setState(state);
        timelinePhoto.setCreateTS(createTS);
        timelinePhoto.setChangeTS(changeTS);
        timelinePhoto.setIsDelete(isDelete);
        timelinePhoto.setIsRemoteDelete(isDelete);
        timelinePhoto.setText(text);
        timelinePhoto.setTheme(theme);
        photoArrayList.add(timelinePhoto);
    }

    private void insertOrReplaceInTxTimelinePhotoUrlByServer(TimelinePhotoUrlDao timelinePhotoUrlDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, int count, String[] urls, ArrayList<TimelinePhotoUrl> photoUrlArrayList) {
        for (int j = 0; j < count; j++) {
            String url = urls[j];
            TimelinePhotoUrl timelinePhotoUrl = timelinePhotoUrlDao.queryBuilder()
                    .where(
                            TimelinePhotoUrlDao.Properties.Uuid.eq(uuid),
                            TimelinePhotoUrlDao.Properties.Url.eq(url))
                    .unique();
            if (timelinePhotoUrl == null) {
                timelinePhotoUrl = new TimelinePhotoUrl();
            } else {
                insertOrReplaceTimelineDelete(timelinePhotoUrl.getLocalThumbUrl());
                insertOrReplaceTimelineDelete(timelinePhotoUrl.getLocalUrl());
            }
            timelinePhotoUrl.setBabyID(babyID);
            timelinePhotoUrl.setUuid(uuid);
            timelinePhotoUrl.setUserID(userID);
            timelinePhotoUrl.setRole(role);
            timelinePhotoUrl.setState(state);

            timelinePhotoUrl.setCreateTS(createTS + j);
            timelinePhotoUrl.setChangeTS(changeTS + j);

            /*timelinePhotoUrl.setDeleteTS(createTS+j);
            timelinePhotoUrl.setChangeTS(changeTS+j);*/
            timelinePhotoUrl.setIsDelete(isDelete);
            timelinePhotoUrl.setIsRemoteDelete(isDelete);
            timelinePhotoUrl.setIsRemoteExist(1);
            timelinePhotoUrl.setIsLocalExist(0);
            timelinePhotoUrl.setIsSyncError(0);
            timelinePhotoUrl.setIsUploadError(0);
            timelinePhotoUrl.setNumber(j);
            // timelinePhotoUrl.setThumbUrl(Config.createSizeUrl(url, 100));
            timelinePhotoUrl.setUrl(url);
            timelinePhotoUrl.setLocalThumbUrl(null);
            timelinePhotoUrl.setLocalUrl(null);
            photoUrlArrayList.add(timelinePhotoUrl);
        }
    }

    private void insertOrReplaceInTxTimelineAudioUrlByServer(TimelineAudioUrlDao timelineAudioUrlDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, int length, String url, ArrayList<TimelineAudioUrl> audioUrlArrayList) {
        TimelineAudioUrl timelineAudioUrl = timelineAudioUrlDao.queryBuilder().where(TimelineAudioUrlDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineAudioUrl == null) {
            timelineAudioUrl = new TimelineAudioUrl();
        } else {
            insertOrReplaceTimelineDelete(timelineAudioUrl.getLocalUrl());
        }
        timelineAudioUrl.setBabyID(babyID);
        timelineAudioUrl.setUuid(uuid);
        timelineAudioUrl.setUserID(userID);
        timelineAudioUrl.setRole(role);
        timelineAudioUrl.setState(state);
        timelineAudioUrl.setCreateTS(createTS);
        timelineAudioUrl.setChangeTS(changeTS);
        timelineAudioUrl.setIsDelete(isDelete);
        timelineAudioUrl.setIsRemoteDelete(isDelete);
        timelineAudioUrl.setIsRemoteExist(1);
        timelineAudioUrl.setIsLocalExist(0);
        timelineAudioUrl.setIsSyncError(0);
        timelineAudioUrl.setIsUploadError(0);
        timelineAudioUrl.setLength(length);
        timelineAudioUrl.setUrl(url);
        timelineAudioUrl.setLocalUrl(null);
        audioUrlArrayList.add(timelineAudioUrl);
    }

    private void insertOrReplaceInTxTimelineVideoScreenshotUrlByServer(TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, String url, ArrayList<TimelineVideoScreenshotUrl> videoScreenshotUrlArrayList) {
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder().where(TimelineVideoScreenshotUrlDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineVideoScreenshotUrl == null) {
            timelineVideoScreenshotUrl = new TimelineVideoScreenshotUrl();
        } else {
            insertOrReplaceTimelineDelete(timelineVideoScreenshotUrl.getLocalUrl());
        }
        timelineVideoScreenshotUrl.setBabyID(babyID);
        timelineVideoScreenshotUrl.setUuid(uuid);
        timelineVideoScreenshotUrl.setUserID(userID);
        timelineVideoScreenshotUrl.setRole(role);
        timelineVideoScreenshotUrl.setState(state);
        timelineVideoScreenshotUrl.setCreateTS(createTS);
        timelineVideoScreenshotUrl.setChangeTS(changeTS);
        timelineVideoScreenshotUrl.setIsDelete(isDelete);
        timelineVideoScreenshotUrl.setIsRemoteDelete(isDelete);
        timelineVideoScreenshotUrl.setIsRemoteExist(1);
        timelineVideoScreenshotUrl.setIsLocalExist(0);
        timelineVideoScreenshotUrl.setIsSyncError(0);
        timelineVideoScreenshotUrl.setIsUploadError(0);
        timelineVideoScreenshotUrl.setUrl(url);
        timelineVideoScreenshotUrl.setLocalUrl(null);
        videoScreenshotUrlArrayList.add(timelineVideoScreenshotUrl);
    }

    private void insertOrReplaceInTxTimelineVideoUrlByServer(TimelineVideoUrlDao timelineVideoUrlDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, int length, String url, ArrayList<TimelineVideoUrl> videoUrlArrayList) {
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().where(TimelineVideoUrlDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineVideoUrl == null) {
            timelineVideoUrl = new TimelineVideoUrl();
        } else {
            insertOrReplaceTimelineDelete(timelineVideoUrl.getLocalUrl());
        }
        timelineVideoUrl.setBabyID(babyID);
        timelineVideoUrl.setUuid(uuid);
        timelineVideoUrl.setUserID(userID);
        timelineVideoUrl.setRole(role);
        timelineVideoUrl.setState(state);
        timelineVideoUrl.setCreateTS(createTS);
        timelineVideoUrl.setChangeTS(changeTS);
        timelineVideoUrl.setIsDelete(isDelete);
        timelineVideoUrl.setIsRemoteDelete(isDelete);
        timelineVideoUrl.setIsRemoteExist(1);
        timelineVideoUrl.setIsLocalExist(0);
        timelineVideoUrl.setIsSyncError(0);
        timelineVideoUrl.setIsUploadError(0);
        timelineVideoUrl.setLength(length);
        timelineVideoUrl.setUrl(url);
        timelineVideoUrl.setLocalUrl(null);
        videoUrlArrayList.add(timelineVideoUrl);
    }

    private void insertOrReplaceInTxTimelineMilestoneByServer(TimelineMilestoneDao timelineMilestoneDao, String uuid, int babyID, String userID, String role, int state, long createTS, long changeTS, int isDelete, String milestone, ArrayList<TimelineMilestone> milestoneArrayList) {
        TimelineMilestone timelineMilestone = timelineMilestoneDao.queryBuilder().where(TimelineMilestoneDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineMilestone == null) {
            timelineMilestone = new TimelineMilestone();
        }
        timelineMilestone.setUuid(uuid);
        timelineMilestone.setBabyID(babyID);
        timelineMilestone.setUserID(userID);
        timelineMilestone.setRole(role);
        timelineMilestone.setState(state);
        timelineMilestone.setCreateTS(createTS);
        timelineMilestone.setChangeTS(changeTS);
        timelineMilestone.setIsDelete(isDelete);
        timelineMilestone.setIsRemoteDelete(isDelete);
        timelineMilestone.setMilestone(milestone);
        milestoneArrayList.add(timelineMilestone);
    }

    private void insertOrReplaceTimelineDelete(String localUrl) {
        openWritableDb();
        if (TextUtils.isEmpty(localUrl)) {
            return;
        }
        TimelineDeleteDao timelineDeleteDao = daoSession.getTimelineDeleteDao();
        TimelineDelete timelineDelete = timelineDeleteDao.queryBuilder().where(TimelineDeleteDao.Properties.LocalUrl.eq(localUrl)).unique();
        if (timelineDelete == null) {
            timelineDelete = new TimelineDelete();
        }
        timelineDelete.setLocalUrl(localUrl);
        timelineDeleteDao.insertOrReplace(timelineDelete);
    }

    /**
     * 查询远程是否存在
     */
    public boolean queryRemoteExist(String uuid) {
        openReadableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder().where(
                TimelineDao.Properties.Uuid.eq(uuid)).unique();
        return timeline != null && timeline.getIsRemoteExist() == 1;
    }

    /**
     * 查询未同步资源
     */
    public Timeline queryUnSyncResTimeline(int babyID) {
        openReadableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(
                        TimelineDao.Properties.BabyID.eq(babyID),
                        TimelineDao.Properties.IsDelete.eq(0),
                        TimelineDao.Properties.IsLocalExist.eq(0),
                        TimelineDao.Properties.IsSyncError.eq(0))
                .orderDesc(TimelineDao.Properties.CreateTS).limit(1).unique();
        if (timeline != null) {
            return timeline;
        }
        return null;
    }

    /**
     * 更新未同步资源
     */
    public void updateUnSyncResTimeline(String uuid) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(TimelineDao.Properties.Uuid.eq(uuid)).unique();
        timeline.setIsLocalExist(1);
        timelineDao.update(timeline);
    }

    /**
     * 更新未同步资源失败
     */
    public void updateUnSyncResTimelineError(String uuid) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(TimelineDao.Properties.Uuid.eq(uuid)).unique();
        timeline.setIsSyncError(1);
        timelineDao.update(timeline);
    }

    /**
     * 查询照片资源
     */
    public TimelinePhotoUrl queryUnSyncTimelinePhotoUrl(String uuid) {
        openReadableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        TimelinePhotoUrl timelinePhotoUrl = timelinePhotoUrlDao.queryBuilder().
                where(
                        TimelinePhotoUrlDao.Properties.Uuid.eq(uuid),
                        TimelinePhotoUrlDao.Properties.IsDelete.eq(0),
                        TimelinePhotoUrlDao.Properties.IsLocalExist.eq(0),
                        TimelinePhotoUrlDao.Properties.IsSyncError.eq(0)).
                orderAsc(TimelinePhotoUrlDao.Properties.Number).limit(1).unique();
        if (timelinePhotoUrl != null) {
            return timelinePhotoUrl;
        }
        return null;
    }

    /**
     * 更新照片资源
     */
    public void updateUnSyncTimelinePhotoUrl(String url, String localThumbUrl) {
        openWritableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        TimelinePhotoUrl timelinePhotoUrl = timelinePhotoUrlDao.queryBuilder().where(TimelinePhotoUrlDao.Properties.Url.eq(url)).unique();
        timelinePhotoUrl.setLocalThumbUrl(localThumbUrl);
        timelinePhotoUrl.setIsLocalExist(1);
        timelinePhotoUrlDao.update(timelinePhotoUrl);
    }

    /**
     * 更新照片资源失败
     */
    public void updateUnSyncTimelinePhotoUrlError(String url) {
        openWritableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        TimelinePhotoUrl timelinePhotoUrl = timelinePhotoUrlDao.queryBuilder().where(TimelinePhotoUrlDao.Properties.Url.eq(url)).unique();
        timelinePhotoUrl.setIsSyncError(1);
        timelinePhotoUrlDao.update(timelinePhotoUrl);
    }

    /**
     * 查询音频资源
     */
    public TimelineAudioUrl queryUnSyncTimelineAudio(String uuid) {
        openReadableDb();
        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        TimelineAudioUrl timelineAudioUrl = timelineAudioUrlDao.queryBuilder().
                where(
                        TimelineAudioUrlDao.Properties.Uuid.eq(uuid),
                        TimelineAudioUrlDao.Properties.IsDelete.eq(0),
                        TimelineAudioUrlDao.Properties.IsLocalExist.eq(0),
                        TimelineAudioUrlDao.Properties.IsSyncError.eq(0)).unique();
        if (timelineAudioUrl != null) {
            return timelineAudioUrl;
        }
        return null;
    }

    /**
     * 查询视频截图资源
     */
    public TimelineVideoScreenshotUrl queryUnSyncTimelineVideoScreenshot(String uuid) {
        openReadableDb();
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder().
                where(
                        TimelineVideoScreenshotUrlDao.Properties.Uuid.eq(uuid),
                        TimelineVideoScreenshotUrlDao.Properties.IsDelete.eq(0),
                        TimelineVideoScreenshotUrlDao.Properties.IsLocalExist.eq(0),
                        TimelineVideoScreenshotUrlDao.Properties.IsSyncError.eq(0))
                .unique();
        if (timelineVideoScreenshotUrl != null) {
            return timelineVideoScreenshotUrl;
        }
        return null;
    }

    /**
     * 查询视频资源
     */
    public String queryTimelineVideoLocalUrl(String uuid) {
        openReadableDb();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().
                where(
                        TimelineVideoUrlDao.Properties.Uuid.eq(uuid),
                        TimelineVideoUrlDao.Properties.IsDelete.eq(0),
                        TimelineVideoUrlDao.Properties.IsLocalExist.eq(1),
                        TimelineVideoUrlDao.Properties.IsSyncError.eq(0)).
                unique();
        if (timelineVideoUrl != null) {
            if (TextUtils.isEmpty(timelineVideoUrl.getLocalUrl())) {
                return null;
            }
            return timelineVideoUrl.getLocalUrl();
        }
        return null;
    }

    /**
     * 更新音频资源
     */
    public void updateUnSyncTimelineAudioUrl(String url, String localUrl) {
        openWritableDb();
        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        TimelineAudioUrl timelineAudioUrl = timelineAudioUrlDao.queryBuilder().where(TimelineAudioUrlDao.Properties.Url.eq(url)).unique();
        timelineAudioUrl.setLocalUrl(localUrl);
        timelineAudioUrlDao.update(timelineAudioUrl);
    }

    /**
     * 更新音频资源失败
     */
    public void updateUnSyncTimelineAudioError(String url) {
        openWritableDb();
        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        TimelineAudioUrl timelineAudioUrl = timelineAudioUrlDao.queryBuilder().where(TimelineAudioUrlDao.Properties.Url.eq(url)).unique();
        timelineAudioUrl.setIsSyncError(1);
        timelineAudioUrlDao.update(timelineAudioUrl);
    }

    /**
     * 更新视频截图资源
     */
    public void updateUnSyncTimelineVideoScreenshotUrl(String url, String localUrl) {
        openWritableDb();
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder().where(TimelineVideoScreenshotUrlDao.Properties.Url.eq(url)).unique();
        timelineVideoScreenshotUrl.setLocalUrl(localUrl);
        timelineVideoScreenshotUrlDao.update(timelineVideoScreenshotUrl);
    }

    /**
     * 更新视频截图资源失败
     */
    public void updateUnSyncTimelineVideoScreenshotUrlError(String url) {
        openWritableDb();
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder().where(TimelineVideoScreenshotUrlDao.Properties.Url.eq(url)).unique();
        timelineVideoScreenshotUrl.setIsSyncError(1);
        timelineVideoScreenshotUrlDao.update(timelineVideoScreenshotUrl);
    }

    /**
     * 更新视频资源
     */
    public void updateUnSyncTimelineVideoUrl(String url, String localUrl) {
        openWritableDb();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().where(TimelineVideoUrlDao.Properties.Url.eq(url)).unique();
        timelineVideoUrl.setLocalUrl(localUrl);
        timelineVideoUrl.setIsLocalExist(1);
        timelineVideoUrlDao.update(timelineVideoUrl);
    }

    /**
     * 更新视频资源
     */
    public void updateUnSyncTimelineVideoUrl(String url) {
        openWritableDb();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().where(TimelineVideoUrlDao.Properties.Url.eq(url)).unique();
        timelineVideoUrl.setLocalUrl(null);
        timelineVideoUrl.setIsLocalExist(0);
        timelineVideoUrlDao.update(timelineVideoUrl);
    }

    /**
     * 更新视频资源失败
     */
    public void updateUnSyncTimelineVideoUrlError(String url) {
        openWritableDb();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().where(TimelineVideoUrlDao.Properties.Url.eq(url)).unique();
        timelineVideoUrl.setIsLocalExist(0);
        timelineVideoUrl.setIsSyncError(1);
        timelineVideoUrlDao.update(timelineVideoUrl);
    }

    /**
     * 查询时间轴
     */
    public List<Timeline> queryTimeline(int babyID, int number, long createTS) {
        openReadableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        QueryBuilder<Timeline> builder = timelineDao.queryBuilder()
                .where(
                        TimelineDao.Properties.BabyID.eq(babyID),
                        TimelineDao.Properties.IsDelete.eq(0),
                        TimelineDao.Properties.CreateTS.lt(createTS));
        builder.orderDesc(TimelineDao.Properties.CreateTS);
        if (number > 0) {
            builder.limit(number);
        }
        return builder.list();
    }

    /**
     * 2.3 修改 查询时间轴
     */
    public List<DTModel> queryOldDiscoverTimeline(int babyID, int number, long createTS) {
        openReadableDb();
        List<DTModel> models = new ArrayList<>();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        QueryBuilder<Discover> builder = discoverDao.queryBuilder().where(DiscoverDao.Properties.BabyID.eq(babyID), DiscoverDao.Properties.DiaryFrom.eq(1), DiscoverDao.Properties.IsDelete.eq(false), DiscoverDao.Properties.CreateTS.lt(createTS));
        builder.orderDesc(DiscoverDao.Properties.CreateTS);
        if (number > 0) {
            builder.limit(number);
        }
        List<Discover> discovers = builder.list();
        if(discovers.size() > 0) {
            DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
            for(int i = 0; i < discovers.size(); i++) {
                DTModel model = new DTModel();
                model.setDiscover(discovers.get(i));
                // 查询评论和赞
                model.setCommentList(getDiscoverAllComments(discovers.get(i).getDiaryID(), 1));
                model.setLikeList(getDiscoverAllComments(discovers.get(i).getDiaryID(), 2));
                // 所有照片
                model.setPhotoList(getDiscoverPhotos(discovers.get(i).getDiaryID()));
                models.add(model);
            }
        }
        return models;
    }

    /**
     * 插入时间轴文字.
     */
    public void insertTimelineText(String uuid, int babyID, String userID, String role, int state, long createTS, String text) {
        openWritableDb();
        insertTimeline(uuid, babyID, userID, role, state, createTS, TypeDataResponse.TYPE_TEXT);
        TimelineText timelineText = new TimelineText();
        timelineText.setUuid(uuid);
        timelineText.setBabyID(babyID);
        timelineText.setUserID(userID);
        timelineText.setRole(role);
        timelineText.setState(state);
        timelineText.setCreateTS(createTS);
        timelineText.setChangeTS((long) 0);
        timelineText.setIsDelete(0);
        timelineText.setIsRemoteDelete(0);
        timelineText.setText(text);
        TimelineTextDao timelineTextDao = daoSession.getTimelineTextDao();
        timelineTextDao.insert(timelineText);
    }

    /**
     * 插入时间轴照片.
     */
    public void insertTimelinePhoto(String uuid, int babyID, String userID, String role, int state, long createTS, String text, String theme, String[] localUrls) {
        openWritableDb();
        insertTimeline(uuid, babyID, userID, role, state, createTS, TypeDataResponse.TYPE_PHOTO);
        /*TimelinePhoto*/
        TimelinePhoto timelinePhoto = new TimelinePhoto();
        timelinePhoto.setUuid(uuid);
        timelinePhoto.setBabyID(babyID);
        timelinePhoto.setUserID(userID);
        timelinePhoto.setRole(role);
        timelinePhoto.setState(state);
        timelinePhoto.setCreateTS(createTS);
        timelinePhoto.setChangeTS(createTS);
        timelinePhoto.setIsDelete(0);
        timelinePhoto.setIsRemoteDelete(0);
        timelinePhoto.setText(text);
        timelinePhoto.setTheme(theme);
        /*TimelinePhotoUrl*/
        int length = localUrls.length;
        TimelinePhotoUrl[] timelinePhotoUrls = new TimelinePhotoUrl[length];
        for (int i = 0; i < length; i++) {
            timelinePhotoUrls[i] = new TimelinePhotoUrl();
            timelinePhotoUrls[i].setUuid(uuid);
            timelinePhotoUrls[i].setBabyID(babyID);
            timelinePhotoUrls[i].setUserID(userID);
            timelinePhotoUrls[i].setRole(role);
            timelinePhotoUrls[i].setCreateTS(createTS + i);
            timelinePhotoUrls[i].setChangeTS(createTS + i);
            timelinePhotoUrls[i].setIsDelete(0);
            timelinePhotoUrls[i].setIsRemoteDelete(0);
            timelinePhotoUrls[i].setIsRemoteExist(0);
            timelinePhotoUrls[i].setIsLocalExist(1);
            timelinePhotoUrls[i].setIsSyncError(0);
            timelinePhotoUrls[i].setIsUploadError(0);
            timelinePhotoUrls[i].setNumber(i);

            timelinePhotoUrls[i].setUrl(null);
            Log.d("什么地址", "" + localUrls[i]);
            timelinePhotoUrls[i].setLocalThumbUrl(localUrls[i]);
            timelinePhotoUrls[i].setLocalUrl(localUrls[i]);
        }
        TimelinePhotoDao timelinePhotoDao = daoSession.getTimelinePhotoDao();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        timelinePhotoDao.insert(timelinePhoto);
        timelinePhotoUrlDao.insertInTx(timelinePhotoUrls);
    }

    /**
     * 插入时间轴音频.
     */
    public void insertTimelineAudio(String uuid, int babyID, String userID, String role, int state, long createTS, int length, String localUrl) {
        openWritableDb();
        insertTimeline(uuid, babyID, userID, role, state, createTS, TypeDataResponse.TYPE_AUDIO);
        /*TimelineAudioUrl*/
        TimelineAudioUrl timelineAudio = new TimelineAudioUrl();
        timelineAudio.setUuid(uuid);
        timelineAudio.setBabyID(babyID);
        timelineAudio.setUserID(userID);
        timelineAudio.setRole(role);
        timelineAudio.setState(state);
        timelineAudio.setCreateTS(createTS);
        timelineAudio.setChangeTS((long) 0);
        timelineAudio.setIsDelete(0);
        timelineAudio.setIsRemoteDelete(0);
        timelineAudio.setIsRemoteExist(0);
        timelineAudio.setIsLocalExist(1);
        timelineAudio.setIsSyncError(0);
        timelineAudio.setIsUploadError(0);
        timelineAudio.setLength(length);
        timelineAudio.setUrl(null);
        timelineAudio.setLocalUrl(localUrl);
        TimelineAudioUrlDao timelineAudioDao = daoSession.getTimelineAudioUrlDao();
        timelineAudioDao.insert(timelineAudio);
    }

    public void insertTimelineVideo(String uuid, int babyID, String userID, String role, int state, long createTS, String screenshotUrl, int length, String localUrl) {
        openWritableDb();
        insertTimeline(uuid, babyID, userID, role, state, createTS, TypeDataResponse.TYPE_VIDEO);
        /*TimelineVideoScreenshotUrl*/
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = new TimelineVideoScreenshotUrl();
        timelineVideoScreenshotUrl.setUuid(uuid);
        timelineVideoScreenshotUrl.setBabyID(babyID);
        timelineVideoScreenshotUrl.setUserID(userID);
        timelineVideoScreenshotUrl.setRole(role);
        timelineVideoScreenshotUrl.setState(state);
        timelineVideoScreenshotUrl.setCreateTS(createTS);
        timelineVideoScreenshotUrl.setChangeTS((long) 0);
        timelineVideoScreenshotUrl.setIsDelete(0);
        timelineVideoScreenshotUrl.setIsRemoteDelete(0);
        timelineVideoScreenshotUrl.setIsRemoteExist(0);
        timelineVideoScreenshotUrl.setIsLocalExist(1);
        timelineVideoScreenshotUrl.setIsSyncError(0);
        timelineVideoScreenshotUrl.setIsUploadError(0);
        timelineVideoScreenshotUrl.setUrl(null);
        timelineVideoScreenshotUrl.setLocalUrl(screenshotUrl);
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        timelineVideoScreenshotUrlDao.insert(timelineVideoScreenshotUrl);
        /*TimelineAudioUrl*/
        TimelineVideoUrl timelineVideoUrl = new TimelineVideoUrl();
        timelineVideoUrl.setUuid(uuid);
        timelineVideoUrl.setBabyID(babyID);
        timelineVideoUrl.setUserID(userID);
        timelineVideoUrl.setRole(role);
        timelineVideoUrl.setCreateTS(createTS);
        timelineVideoUrl.setChangeTS((long) 0);
        timelineVideoUrl.setIsDelete(0);
        timelineVideoUrl.setIsRemoteDelete(0);
        timelineVideoUrl.setIsRemoteExist(0);
        timelineVideoUrl.setIsLocalExist(1);
        timelineVideoUrl.setIsSyncError(0);
        timelineVideoUrl.setIsUploadError(0);
        timelineVideoUrl.setLength(length);
        timelineVideoUrl.setUrl(null);
        timelineVideoUrl.setLocalUrl(localUrl);
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        timelineVideoUrlDao.insert(timelineVideoUrl);
    }

    /**
     * 插入时间轴里程碑.
     */
    public void insertTimelineMilestone(String uuid, int babyID, String userID, String role, int state, long createTS, int milestoneID, String milestone) {
        openWritableDb();
        insertTimeline(uuid, babyID, userID, role, state, createTS, TypeDataResponse.TYPE_MILESTONE);
        TimelineMilestone timelineMilestone = new TimelineMilestone();
        timelineMilestone.setUuid(uuid);
        timelineMilestone.setBabyID(babyID);
        timelineMilestone.setUserID(userID);
        timelineMilestone.setRole(role);
        timelineMilestone.setState(state);
        timelineMilestone.setCreateTS(createTS);
        timelineMilestone.setChangeTS((long) 0);
        timelineMilestone.setIsDelete(0);
        timelineMilestone.setIsRemoteDelete(0);
        timelineMilestone.setMilestoneID(milestoneID);
        timelineMilestone.setMilestone(milestone);
        TimelineMilestoneDao timelineMilestoneDao = daoSession.getTimelineMilestoneDao();
        timelineMilestoneDao.insert(timelineMilestone);
    }

    /*插入时间轴*/
    private void insertTimeline(String uuid, int babyID, String userID, String role, int state, long createTS, int type) {
        openWritableDb();
        Timeline timeline = new Timeline();
        timeline.setUuid(uuid);
        timeline.setBabyID(babyID);
        timeline.setUserID(userID);
        timeline.setRole(role);
        timeline.setState(state);
        timeline.setCreateTS(createTS);
        timeline.setChangeTS((long) 0);
        timeline.setIsDelete(0);
        timeline.setIsRemoteDelete(0);
        timeline.setIsRemoteExist(0);
        timeline.setIsLocalExist(1);
        timeline.setIsSyncError(0);
        timeline.setIsUploadError(0);
        timeline.setType(type);
        TimelineDao timelineDao = daoSession.getTimelineDao();
        timelineDao.insert(timeline);
    }

    /**
     * 插入照片主题
     */
    public void insertPhotoThemes(String[] themes) {
        openWritableDb();
        PublicPhotoThemeDao photoThemeDao = daoSession.getPublicPhotoThemeDao();
        int length = themes.length;
        PublicPhotoTheme[] photoThemes = new PublicPhotoTheme[length];
        for (int i = 0; i < length; i++) {
            photoThemes[i] = new PublicPhotoTheme();
            photoThemes[i].setTheme(themes[i]);
        }
        photoThemeDao.insertInTx(photoThemes);
    }

    /**
     * 插入照片主题
     */
    public void insertPublicMilestone(MilestoneGetResponse response) {
        openWritableDb();
        PublicMilestoneDao publicMilestoneDao = daoSession.getPublicMilestoneDao();
        int length = response.getData().length;
        ArrayList<PublicMilestone> list = new ArrayList<PublicMilestone>();
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < response.getData()[i].getValues().length; j++) {
                PublicMilestone publicMilestone = new PublicMilestone();
                publicMilestone.setType(response.getData()[i].getType());
                publicMilestone.setMilestoneID(response.getData()[i].getValues()[j].getId());
                publicMilestone.setMilestone(response.getData()[i].getValues()[j].getMilestone());
                list.add(publicMilestone);
            }
        }
        publicMilestoneDao.insertInTx(list);
    }

    /*Delete*/

    /*Update*/

    public void updateTimelinePhotoUrl(String url, String localUrl) {
        openWritableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        TimelinePhotoUrl timelinePhotoUrl = timelinePhotoUrlDao.queryBuilder()
                .where(TimelinePhotoUrlDao.Properties.LocalUrl.eq(localUrl)).unique();
        if (timelinePhotoUrl == null) {
            return;
        }
        timelinePhotoUrl.setIsRemoteExist(1);
        timelinePhotoUrl.setIsUploadError(0);
        // timelinePhotoUrl.setThumbUrl(Config.createSizeUrl(url, 100));
        timelinePhotoUrl.setUrl(url);
        timelinePhotoUrlDao.update(timelinePhotoUrl);

        // 更新本地的日记的照片地址
        DiscoverPhotoDao photoDao = daoSession.getDiscoverPhotoDao();
        DiscoverPhoto photo = photoDao.queryBuilder().where(DiscoverPhotoDao.Properties.Url.eq(localUrl)).unique();
        if(photo == null) {
            return;
        }
        photo.setUrl(url);
        photoDao.update(photo);
    }

    public void updateTimelineAudioUrl(String url, String localUrl) {
        openWritableDb();
        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        TimelineAudioUrl timelineAudioUrl = timelineAudioUrlDao.queryBuilder()
                .where(TimelineAudioUrlDao.Properties.LocalUrl.eq(localUrl)).unique();
        if (timelineAudioUrl == null) {
            return;
        }
        timelineAudioUrl.setIsRemoteExist(1);
        timelineAudioUrl.setIsUploadError(0);
        timelineAudioUrl.setUrl(url);
        timelineAudioUrlDao.update(timelineAudioUrl);

        // 更新本地的日记的音频地址
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> models = discoverDao.queryBuilder().where(DiscoverDao.Properties.AudioLocalUrl.eq(localUrl)).list();
        if(models.size() > 0) {
            for(Discover model : models) {
                model.setAudio(url);
            }
            discoverDao.updateInTx(models);
        }
    }

    public void updateTimelineVideoScreenshotUrl(String url, String localUrl) {
        openWritableDb();
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder().
                where(TimelineVideoScreenshotUrlDao.Properties.LocalUrl.eq(localUrl)).unique();
        if (timelineVideoScreenshotUrl == null) {
            return;
        }
        timelineVideoScreenshotUrl.setIsRemoteExist(1);
        timelineVideoScreenshotUrl.setIsUploadError(0);
        timelineVideoScreenshotUrl.setUrl(url);
        timelineVideoScreenshotUrlDao.update(timelineVideoScreenshotUrl);

        // 更新本地的日记的视频截图
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> models = discoverDao.queryBuilder().where(DiscoverDao.Properties.Screenshot.eq(localUrl)).list();
        if(models.size() > 0) {
            for(Discover model : models) {
                model.setScreenshot(url);
            }
            discoverDao.updateInTx(models);
        }
    }

    public void updateTimelineVideoUrl(String url, String localUrl) {
        openWritableDb();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().
                where(TimelineVideoUrlDao.Properties.LocalUrl.eq(localUrl)).unique();
        if (timelineVideoUrl == null) {
            return;
        }
        timelineVideoUrl.setIsRemoteExist(1);
        timelineVideoUrl.setIsUploadError(0);
        timelineVideoUrl.setUrl(url);
        timelineVideoUrlDao.update(timelineVideoUrl);

        // 更新本地的日记的视频地址
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> models = discoverDao.queryBuilder().where(DiscoverDao.Properties.VideoLocalUrl.eq(localUrl)).list();
        if(models.size() > 0) {
            for(Discover model : models) {
                model.setVideo(url);
            }
            discoverDao.updateInTx(models);
        }
    }

    public void updateTimeline(String uuid) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder().where(TimelineDao.Properties.Uuid.eq(uuid)).unique();
        timeline.setIsRemoteExist(1);
        timeline.setIsUploadError(0);
        timelineDao.update(timeline);

        // 更新本地日记的状态
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> models = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(uuid)).list();
        if(models.size() > 0) {
            for(Discover model : models) {
                model.setIsLocal(false);
            }
            discoverDao.updateInTx(models);
        }
    }

    /*Query*/

    /**
     * 通过宝贝标识查询宝贝信息
     */
    public Baby[] queryBabyAll(String userID) {
        openReadableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        List<BabyAndParent> babyAndParentList = babyAndParentDao.queryBuilder().where(BabyAndParentDao.Properties.ParentID.eq(userID)).orderAsc(BabyAndParentDao.Properties.Number).list();

        BabyDao babyDao = daoSession.getBabyDao();
        Baby[] babies = new Baby[babyAndParentList.size()];
        for (int i = 0; i < babyAndParentList.size(); i++) {
            babies[i] = babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(babyAndParentList.get(i).getBabyID())).unique();
        }
        return babies;
    }

    /**
     * 查询当前宝贝ID
     */
    public int queryBabyID(String userID, int position) {
        openReadableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        BabyAndParent babyAndParent = babyAndParentDao.queryBuilder().where(BabyAndParentDao.Properties.ParentID.eq(userID), BabyAndParentDao.Properties.Number.eq(position)).unique();
        return babyAndParent.getBabyID();
    }

    public int queryBabyPosition(String userId, int babyID) {
        openReadableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        BabyAndParent babyAndParent = babyAndParentDao.queryBuilder().where(BabyAndParentDao.Properties.BabyID.eq(babyID), BabyAndParentDao.Properties.ParentID.eq(userId)).unique();
        if (babyAndParent != null) {
            return babyAndParent.getNumber();
        }
        return -1;
    }

    /**
     * 通过宝贝标识查询宝贝信息
     */
    public Baby queryBaby(String userId, int babyID) {
        openReadableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        BabyAndParent babyAndParent = babyAndParentDao.queryBuilder().where(BabyAndParentDao.Properties.ParentID.eq(userId), BabyAndParentDao.Properties.BabyID.eq(babyID)).unique();
        if (babyAndParent == null) {
            return null;
        }
        BabyDao babyDao = daoSession.getBabyDao();
        Baby baby = babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(babyID)).unique();
        if(TextUtils.isEmpty(baby.getImageUrl())) {
            baby.setImageUrl("");
        }
        return baby;
    }

    public Baby queryBaby(int babyID) {
        openReadableDb();
        BabyDao babyDao = daoSession.getBabyDao();
        return babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(babyID)).unique();
    }

    /**
     * 查询宝贝与用户关系
     *
     * @param userId userId
     * @param babyId babyId
     * @return 宝贝与用户关系
     */
    public BabyAndParent queryBabyAndParent(String userId, int babyId) {
        openReadableDb();
        BabyAndParentDao babyAndParentDao = daoSession.getBabyAndParentDao();
        return babyAndParentDao.queryBuilder().where(
                BabyAndParentDao.Properties.ParentID.eq(userId),
                BabyAndParentDao.Properties.BabyID.eq(babyId)).unique();
    }

    /**
     * 通过宝贝标识和查询数量查询时间轴,并升序返回.
     */
    public List<Timeline> queryTimeline(int babyID, int number) {
        openReadableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        QueryBuilder<Timeline> builder = timelineDao.queryBuilder().where(TimelineDao.Properties.BabyID.eq(babyID), TimelineDao.Properties.IsDelete.eq(0));
        builder.orderDesc(TimelineDao.Properties.CreateTS);
        if (number > 0) {
            builder.limit(number);
        }
        return builder.list();
    }

    /**
     * 2.3 修改 通过宝贝标识和查询数量查询时间轴,并升序返回.
     */
    public List<DTModel> queryDiscoverTimeline(int babyID, int number) {
        openReadableDb();
        List<DTModel> models = new ArrayList<>();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        QueryBuilder<Discover> builder = discoverDao.queryBuilder().where(DiscoverDao.Properties.BabyID.eq(babyID), DiscoverDao.Properties.DiaryFrom.eq(1), DiscoverDao.Properties.IsDelete.eq(false));
        builder.orderDesc(DiscoverDao.Properties.CreateTS);
        if (number > 0) {
            builder.limit(number);
        }
        List<Discover> discovers = builder.list();
        if(discovers.size() > 0) {
            DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
            for(int i = 0; i < discovers.size(); i++) {
                DTModel model = new DTModel();
                model.setDiscover(discovers.get(i));
                // 查询评论和赞
                model.setCommentList(getDiscoverAllComments(discovers.get(i).getDiaryID(), 1));
                model.setLikeList(getDiscoverAllComments(discovers.get(i).getDiaryID(), 2));
                // 所有照片
                model.setPhotoList(getDiscoverPhotos(discovers.get(i).getDiaryID()));
                models.add(model);
            }
        }
        return models;
    }

    /**
     * 查询未同步的时间轴
     */
    public Timeline queryUnSyncTimeline(/**int babyID, **/String userID) {
        openReadableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(
//                        TimelineDao.Properties.BabyID.eq(babyID),
                        TimelineDao.Properties.UserID.eq(userID),
                        TimelineDao.Properties.IsRemoteExist.eq(0),
                        TimelineDao.Properties.IsUploadError.eq(0),
                        TimelineDao.Properties.IsDelete.eq(0))
                .orderAsc(TimelineDao.Properties.CreateTS)
                .limit(1).unique();
        if (timeline != null) {
            return timeline;
        }
        return null;
    }

    /**
     * 查询时间轴文字
     */
    public TimelineText queryTimelineText(String uuid) {
        openReadableDb();
        TimelineTextDao timelineTextDao = daoSession.getTimelineTextDao();
        TimelineText timelineText = timelineTextDao.queryBuilder()
                .where(TimelineTextDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineText == null) {
            return null;
        }
        return timelineText;
    }

    /**
     * 查询时间轴照片
     */
    public TimelinePhoto queryTimelinePhoto(String uuid) {
        openReadableDb();
        TimelinePhotoDao timelinePhotoDao = daoSession.getTimelinePhotoDao();
        TimelinePhoto timelinePhoto = timelinePhotoDao.queryBuilder()
                .where(TimelinePhotoDao.Properties.Uuid.eq(uuid)).unique();
        if (timelinePhoto == null) {
            return null;
        }
        return timelinePhoto;
    }

    /**
     * 查询时间轴照片路径
     */
    public TimelinePhotoUrl queryTimelinePhotoUrl(String uuid, int IsRemoteExist) {
        openReadableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        return timelinePhotoUrlDao.queryBuilder()
                .where(
                        TimelinePhotoUrlDao.Properties.Uuid.eq(uuid),
                        TimelinePhotoUrlDao.Properties.IsRemoteExist.eq(IsRemoteExist))
                .limit(1).unique();
    }

    /**
     * 查询时间轴音频
     */
    public TimelineAudioUrl queryTimelineAudioUrl(String uuid) {
        openReadableDb();
        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        TimelineAudioUrl timelineAudioUrl = timelineAudioUrlDao.queryBuilder()
                .where(TimelineAudioUrlDao.Properties.Uuid.eq(uuid))
                .unique();
        if (timelineAudioUrl == null) {
            return null;
        }
        return timelineAudioUrl;
    }

    /**
     * 查询时间轴视频截图
     */
    public TimelineVideoScreenshotUrl queryTimelineVideoScreenshotUrl(String uuid) {
        openReadableDb();
        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder()
                .where(TimelineVideoScreenshotUrlDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineVideoScreenshotUrl == null) {
            return null;
        }
        return timelineVideoScreenshotUrl;
    }

    /**
     * 查询时间轴视频
     */
    public TimelineVideoUrl queryTimelineVideoUrl(String uuid) {
        openReadableDb();
        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        TimelineVideoUrl timelineVideoUrl = timelineVideoUrlDao.queryBuilder().
                where(TimelineVideoUrlDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineVideoUrl == null) {
            return null;
        }
        return timelineVideoUrl;
    }

    /**
     * 查询时间轴照片路径(服务器地址)
     */
    public String[] queryTimelinePhotoUrlUrls(String uuid) {
        openReadableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        List<TimelinePhotoUrl> timelinePhotoUrls = timelinePhotoUrlDao.queryBuilder()
                .where(TimelinePhotoUrlDao.Properties.Uuid.eq(uuid)).list();
        int length = timelinePhotoUrls.size();
        String[] urls = new String[length];
        for (int i = 0; i < length; i++) {
            urls[i] = timelinePhotoUrls.get(i).getUrl();
        }
        return urls;
    }

    /**
     * 查询时间轴里程碑
     */
    public TimelineMilestone queryTimelineMilestone(String uuid) {
        openReadableDb();
        TimelineMilestoneDao timelineMilestoneDao = daoSession.getTimelineMilestoneDao();
        TimelineMilestone timelineMilestone = timelineMilestoneDao.queryBuilder()
                .where(TimelineMilestoneDao.Properties.Uuid.eq(uuid)).unique();
        if (timelineMilestone == null) {
            return null;
        }
        return timelineMilestone;
    }

    /**
     * 标记未同步的日记为删除状态
     * @param uuid
     */
    public void deleteUnSyncTimeline(String uuid) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(
                        TimelineDao.Properties.Uuid.eq(uuid),
                        TimelineDao.Properties.IsDelete.eq(0)
                ).unique();
        if(timeline == null) {
            return;
        }
        timeline.setIsDelete(1);
        timelineDao.update(timeline);
        int type = timeline.getType();
        switch (type) {
            case TypeDataResponse.TYPE_TEXT:
                TimelineTextDao timelineTextDao = daoSession.getTimelineTextDao();
                TimelineText timelineText = timelineTextDao.queryBuilder()
                        .where(
                                TimelineTextDao.Properties.Uuid.eq(uuid),
                                TimelineTextDao.Properties.IsDelete.eq(0)
                        ).unique();
                timelineText.setIsDelete(1);
                timelineTextDao.update(timelineText);
                break;
            case TypeDataResponse.TYPE_PHOTO:
                TimelinePhotoDao timelinePhotoDao = daoSession.getTimelinePhotoDao();
                TimelinePhoto timelinePhoto = timelinePhotoDao.queryBuilder()
                        .where(
                                TimelinePhotoDao.Properties.Uuid.eq(uuid),
                                TimelinePhotoDao.Properties.IsDelete.eq(0)
                        ).unique();
                timelinePhoto.setIsDelete(1);
                timelinePhotoDao.update(timelinePhoto);

                TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
                List<TimelinePhotoUrl> timelinePhotoUrlList = timelinePhotoUrlDao.queryBuilder()
                        .where(
                                TimelinePhotoUrlDao.Properties.Uuid.eq(uuid),
                                TimelinePhotoUrlDao.Properties.IsDelete.eq(0)
                        ).list();
                for (TimelinePhotoUrl timelinePhotoUrl : timelinePhotoUrlList) {
                    timelinePhotoUrl.setIsDelete(1);
                }
                timelinePhotoUrlDao.updateInTx(timelinePhotoUrlList);
                break;
            case TypeDataResponse.TYPE_AUDIO:
                TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
                List<TimelineAudioUrl> timelineAudioUrlList = timelineAudioUrlDao.queryBuilder()
                        .where(
                                TimelineAudioUrlDao.Properties.Uuid.eq(uuid),
                                TimelineAudioUrlDao.Properties.IsDelete.eq(0)
                        ).list();
                for (TimelineAudioUrl timelineAudioUrl : timelineAudioUrlList) {
                    timelineAudioUrl.setIsDelete(1);
                }
                timelineAudioUrlDao.updateInTx(timelineAudioUrlList);
                break;
            case TypeDataResponse.TYPE_VIDEO:
                TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
                TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder()
                        .where(
                                TimelineVideoScreenshotUrlDao.Properties.Uuid.eq(uuid),
                                TimelineVideoScreenshotUrlDao.Properties.IsDelete.eq(0)
                        ).unique();
                timelineVideoScreenshotUrl.setIsDelete(1);
                timelineVideoScreenshotUrlDao.update(timelineVideoScreenshotUrl);

                TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
                List<TimelineVideoUrl> timelineVideoUrlList = timelineVideoUrlDao.queryBuilder()
                        .where(
                                TimelineVideoUrlDao.Properties.Uuid.eq(uuid),
                                TimelineVideoUrlDao.Properties.IsDelete.eq(0)
                        ).list();
                for (TimelineVideoUrl timelineVideoUrl : timelineVideoUrlList) {
                    timelineVideoUrl.setIsDelete(1);
                }
                timelineVideoUrlDao.updateInTx(timelineVideoUrlList);
                break;
            case TypeDataResponse.TYPE_MILESTONE:
                TimelineMilestoneDao timelineMilestoneDao = daoSession.getTimelineMilestoneDao();
                TimelineMilestone timelineMilestone = timelineMilestoneDao.queryBuilder()
                        .where(
                                TimelineMilestoneDao.Properties.Uuid.eq(uuid),
                                TimelineMilestoneDao.Properties.IsDelete.eq(0)
                        ).unique();
                timelineMilestone.setIsDelete(1);
                timelineMilestoneDao.update(timelineMilestone);
                break;
        }
        // 删除日记
        deleteDiscover(uuid);
    }

    // 彻底删除日记
    public void deleteDiscover(String diaryId) {
        openWritableDb();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        discoverDao.deleteInTx(discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(diaryId)).list());
        // 删除日记下的所有评论
        DiscoverSaveCommentDao discoverSaveCommentDao = daoSession.getDiscoverSaveCommentDao();
        discoverSaveCommentDao.deleteInTx(discoverSaveCommentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.DiaryID.eq(diaryId)).list());
        // 删除日记下面所有的照片
        DiscoverPhotoDao discoverPhotoDao = daoSession.getDiscoverPhotoDao();
        discoverPhotoDao.deleteInTx(discoverPhotoDao.queryBuilder().where(DiscoverPhotoDao.Properties.DiscoverID.eq(diaryId)).list());
    }

    // 删除日记圈缓存的最新日记，不删除评论
    public void deleteRjqDiscover() {
        openWritableDb();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        discoverDao.deleteInTx(discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryFrom.eq(2)).list());
    }

    // 获取日记圈缓存的日记
    public List<DiscoverModel> getLocalDiscover() {
        openReadableDb();
        List<DiscoverModel> models = new ArrayList<>();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> discovers = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryFrom.eq(2)).list();
        for(Discover discover : discovers) {
            DiscoverModel model = new DiscoverModel();
            DiscoverContentResponse diariesContent = new DiscoverContentResponse();
            diariesContent.setAudio(discover.getAudio());
            diariesContent.setAudioLocalUrl(discover.getAudioLocalUrl());
            diariesContent.setBabyHeadUrl(discover.getBabyHeadUrl());
            diariesContent.setBabyId(discover.getBabyID());
            diariesContent.setBabyName(discover.getBabyName());
            diariesContent.setCreateTS(discover.getCreateTS());
            diariesContent.setDiaryId(discover.getDiaryID());
            diariesContent.setDiaryName(discover.getDiaryName());
            diariesContent.setHeadUrl(discover.getUserHeadUrl());
            diariesContent.setMediaLength(discover.getDuration());
            diariesContent.setMilestone(discover.getMilestone());
            diariesContent.setName(discover.getMemberName());
            diariesContent.setNickName(discover.getNickName());
            diariesContent.setScreenshot(discover.getScreenshot());
            diariesContent.setVideo(discover.getVideo());
            diariesContent.setState(discover.getGrowthStageID());
            diariesContent.setTheme(discover.getTheme());
            diariesContent.setType(discover.getType());
            diariesContent.setUserId(discover.getUserID());
            diariesContent.setText(discover.getText());
            ArrayList<DiscoverPhoto> photos = getDiscoverPhotos(discover.getDiaryID());
            String[] arrayPhotos = new String[photos.size()];
            for(int i = 0; i < photos.size(); i++) {
                arrayPhotos[i] = photos.get(i).getUrl();
            }
            diariesContent.setPhotos(arrayPhotos);
            model.setContent(diariesContent);
            model.setComment(new ArrayList<DiscoverCommentResponse>());
            // 评论和赞
            ArrayList<DiscoverSaveComment> comments = getDiscoverAllComments(discover.getDiaryID(), 1);
            for(int i = 0; i < comments.size(); i++) {
                DiscoverCommentResponse commentResponse = new DiscoverCommentResponse();
                commentResponse.setComment(comments.get(i).getContent());
                commentResponse.setCommentHeadUrl(comments.get(i).getUserHeadUrl());
                commentResponse.setCommentId(comments.get(i).getUserID());
                commentResponse.setCommentName(comments.get(i).getMemberName());
                commentResponse.setCommentNickname(comments.get(i).getUserNickname());
                commentResponse.setCommentState(comments.get(i).getOperationState());
                commentResponse.setId(comments.get(i).getIdentity());
                commentResponse.setDiaryId(comments.get(i).getDiaryID());
                commentResponse.setTargetId(comments.get(i).getReplyIdentity());
                commentResponse.setTargetName(comments.get(i).getReplyMemberName());
                commentResponse.setTargetNickname(comments.get(i).getReplyNickname());
                commentResponse.setTargetUserId(comments.get(i).getReplyUserID());
                commentResponse.setTs(comments.get(i).getCreateTS());
                model.getComment().add(commentResponse);
            }
            model.setLike(new ArrayList<DiscoverLikeResponse>());
            ArrayList<DiscoverSaveComment> likes = getDiscoverAllComments(discover.getDiaryID(), 2);
            for(int i = 0; i < likes.size(); i++) {
                DiscoverLikeResponse likeResponse = new DiscoverLikeResponse();
                likeResponse.setLikeId(likes.get(i).getUserID());
                likeResponse.setLikeHeadUrl(likes.get(i).getUserHeadUrl());
                likeResponse.setLikeName(likes.get(i).getMemberName());
                likeResponse.setLikeNickname(likes.get(i).getUserNickname());
                likeResponse.setLikeState(likes.get(i).getOperationState());
                likeResponse.setDiaryId(likes.get(i).getDiaryID());
                likeResponse.setTs(likes.get(i).getCreateTS());
                model.getLike().add(likeResponse);
            }
            models.add(model);
        }
        return models;
    }

    // 查询某个宝宝所有本地的视频4，照片2日记
    public List<Discover> getLocalDiscover(int babyId, int type, long ts, int pageSize) {
        openReadableDb();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        return discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryFrom.eq(1), DiscoverDao.Properties.Type.eq(type), DiscoverDao.Properties.BabyID.eq(babyId), DiscoverDao.Properties.CreateTS.lt(ts)).orderDesc(DiscoverDao.Properties.CreateTS).limit(pageSize).list();
    }

    // 删除某个宝宝所有的日记
    public void deleteBabyDiary(int babyId) {
        openWritableDb();
        // 删除日记信息
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        discoverDao.deleteInTx(discoverDao.queryBuilder().where(DiscoverDao.Properties.BabyID.eq(babyId)).list());
        // 删除同步时间戳
        TimelineLastServerTimeDao lastServerTimeDao = daoSession.getTimelineLastServerTimeDao();
        lastServerTimeDao.deleteInTx(lastServerTimeDao.queryBuilder().where(TimelineLastServerTimeDao.Properties.BabyID.eq(babyId)).list());
        TimelineServerTimeDao serverTimeDao = daoSession.getTimelineServerTimeDao();
        serverTimeDao.deleteInTx(serverTimeDao.queryBuilder().where(TimelineServerTimeDao.Properties.BabyID.eq(babyId)).list());
    }

    public String queryDeleteTimeline(int babyID) {
        openReadableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(
                        TimelineDao.Properties.BabyID.eq(babyID),
                        TimelineDao.Properties.IsDelete.eq(1),
                        TimelineDao.Properties.IsRemoteDelete.eq(0),
                        TimelineDao.Properties.IsRemoteExist.eq(1)).limit(1).unique();
        if (timeline != null) {
            return timeline.getUuid();
        }
        return null;
    }

    // 彻底删除 Timeline
    public void deleteTimeline(String uuid) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        Timeline timeline = timelineDao.queryBuilder()
                .where(
                        TimelineDao.Properties.Uuid.eq(uuid)
                ).unique();
        if (timeline != null) {
            int type = timeline.getType();
            switch (type) {
                case TypeDataResponse.TYPE_TEXT:
                    TimelineTextDao timelineTextDao = daoSession.getTimelineTextDao();
                    TimelineText timelineText = timelineTextDao.queryBuilder()
                            .where(
                                    TimelineTextDao.Properties.Uuid.eq(uuid)
                            ).unique();
                    timelineTextDao.delete(timelineText);
                    break;
                case TypeDataResponse.TYPE_PHOTO:
                    TimelinePhotoDao timelinePhotoDao = daoSession.getTimelinePhotoDao();
                    TimelinePhoto timelinePhoto = timelinePhotoDao.queryBuilder()
                            .where(
                                    TimelinePhotoDao.Properties.Uuid.eq(uuid)
                            ).unique();
                    timelinePhotoDao.delete(timelinePhoto);

                    TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
                    List<TimelinePhotoUrl> timelinePhotoUrlList = timelinePhotoUrlDao.queryBuilder()
                            .where(
                                    TimelinePhotoUrlDao.Properties.Uuid.eq(uuid)
                            ).list();
                    timelinePhotoUrlDao.deleteInTx(timelinePhotoUrlList);
                    break;
                case TypeDataResponse.TYPE_AUDIO:
                    TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
                    List<TimelineAudioUrl> timelineAudioUrlList = timelineAudioUrlDao.queryBuilder()
                            .where(
                                    TimelineAudioUrlDao.Properties.Uuid.eq(uuid)
                            ).list();
                    timelineAudioUrlDao.deleteInTx(timelineAudioUrlList);
                    break;
                case TypeDataResponse.TYPE_VIDEO:
                    TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
                    TimelineVideoScreenshotUrl timelineVideoScreenshotUrl = timelineVideoScreenshotUrlDao.queryBuilder()
                            .where(
                                    TimelineVideoScreenshotUrlDao.Properties.Uuid.eq(uuid)
                            ).unique();
                    timelineVideoScreenshotUrl.setIsRemoteDelete(1);
                    timelineVideoScreenshotUrlDao.update(timelineVideoScreenshotUrl);

                    TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
                    List<TimelineVideoUrl> timelineVideoUrlList = timelineVideoUrlDao.queryBuilder()
                            .where(
                                    TimelineVideoUrlDao.Properties.Uuid.eq(uuid)
                            ).list();
                    timelineVideoUrlDao.deleteInTx(timelineVideoUrlList);
                    break;
                case TypeDataResponse.TYPE_MILESTONE:
                    TimelineMilestoneDao timelineMilestoneDao = daoSession.getTimelineMilestoneDao();
                    TimelineMilestone timelineMilestone = timelineMilestoneDao.queryBuilder()
                            .where(
                                    TimelineMilestoneDao.Properties.Uuid.eq(uuid)
                            ).unique();
                    timelineMilestoneDao.delete(timelineMilestone);
                    break;
            }
            timelineDao.delete(timeline);
        }

        // 删除日记，设置删除标记
        deleteDiscover(uuid);
    }

    /**
     * 删除日记下所有相关评论
     */
    public void deleteAllDiscoverSaveComment(String diaryId) {
        openWritableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        commentDao.deleteInTx(commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.DiaryID.eq(diaryId)).list());
    }

    /*旧方法*/

    public TimelinePhotoUrl[] queryTimelinePhotoUrls(String uuid) {
        openReadableDb();
        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        List<TimelinePhotoUrl> list = timelinePhotoUrlDao.queryBuilder()
                .where(TimelinePhotoUrlDao.Properties.Uuid.eq(uuid)).list();
        return list.toArray(new TimelinePhotoUrl[list.size()]);
    }

    public PublicPhotoTheme[] queryPhotoThemes() {
        openReadableDb();
        PublicPhotoThemeDao photoThemeDao = daoSession.getPublicPhotoThemeDao();
        List<PublicPhotoTheme> list = photoThemeDao.queryBuilder().list();
        if (list != null && list.size() > 0) {
            return list.toArray(new PublicPhotoTheme[list.size()]);
        }
        return null;
    }

    public PublicMilestone[] queryPublicMilestone() {
        openReadableDb();
        PublicMilestoneDao publicMilestoneDao = daoSession.getPublicMilestoneDao();
        List<PublicMilestone> list = publicMilestoneDao.queryBuilder().list();
        if (list != null && list.size() > 0) {
            return list.toArray(new PublicMilestone[list.size()]);
        }
        return null;
    }

    public void updateRole(int babyID, String oldRole, String newRole) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        List<Timeline> timelineList = timelineDao.queryBuilder()
                .where(
                        TimelineDao.Properties.BabyID.eq(babyID),
                        TimelineDao.Properties.Role.eq(oldRole))
                .list();
        for (Timeline timeline : timelineList) {
            timeline.setRole(newRole);
        }

        TimelineTextDao timelineTextDao = daoSession.getTimelineTextDao();
        List<TimelineText> timelineTextList = timelineTextDao.queryBuilder()
                .where(
                        TimelineTextDao.Properties.BabyID.eq(babyID),
                        TimelineTextDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelineText timelineText : timelineTextList) {
            timelineText.setRole(newRole);
        }

        TimelinePhotoDao timelinePhotoDao = daoSession.getTimelinePhotoDao();
        List<TimelinePhoto> timelinePhotoList = timelinePhotoDao.queryBuilder()
                .where(
                        TimelinePhotoDao.Properties.BabyID.eq(babyID),
                        TimelinePhotoDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelinePhoto timelinePhoto : timelinePhotoList) {
            timelinePhoto.setRole(newRole);
        }

        TimelinePhotoUrlDao timelinePhotoUrlDao = daoSession.getTimelinePhotoUrlDao();
        List<TimelinePhotoUrl> timelinePhotoUrlList = timelinePhotoUrlDao.queryBuilder()
                .where(
                        TimelinePhotoUrlDao.Properties.BabyID.eq(babyID),
                        TimelinePhotoUrlDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelinePhotoUrl timelinePhotoUrl : timelinePhotoUrlList) {
            timelinePhotoUrl.setRole(newRole);
        }

        TimelineAudioUrlDao timelineAudioUrlDao = daoSession.getTimelineAudioUrlDao();
        List<TimelineAudioUrl> timelineAudioUrlList = timelineAudioUrlDao.queryBuilder()
                .where(
                        TimelineAudioUrlDao.Properties.BabyID.eq(babyID),
                        TimelineAudioUrlDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelineAudioUrl timelineAudioUrl : timelineAudioUrlList) {
            timelineAudioUrl.setRole(newRole);
        }

        TimelineVideoScreenshotUrlDao timelineVideoScreenshotUrlDao = daoSession.getTimelineVideoScreenshotUrlDao();
        List<TimelineVideoScreenshotUrl> timelineVideoScreenshotUrlList = timelineVideoScreenshotUrlDao.queryBuilder()
                .where(
                        TimelineVideoScreenshotUrlDao.Properties.BabyID.eq(babyID),
                        TimelineVideoScreenshotUrlDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelineVideoScreenshotUrl timelineVideoScreenshotUrl : timelineVideoScreenshotUrlList) {
            timelineVideoScreenshotUrl.setRole(newRole);
        }

        TimelineVideoUrlDao timelineVideoUrlDao = daoSession.getTimelineVideoUrlDao();
        List<TimelineVideoUrl> timelineVideoUrlList = timelineVideoUrlDao.queryBuilder()
                .where(
                        TimelineVideoUrlDao.Properties.BabyID.eq(babyID),
                        TimelineVideoUrlDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelineVideoUrl timelineVideoUrl : timelineVideoUrlList) {
            timelineVideoUrl.setRole(newRole);
        }

        TimelineMilestoneDao timelineMilestoneDao = daoSession.getTimelineMilestoneDao();
        List<TimelineMilestone> timelineMilestoneList = timelineMilestoneDao.queryBuilder()
                .where(
                        TimelineMilestoneDao.Properties.BabyID.eq(babyID),
                        TimelineMilestoneDao.Properties.Role.eq(oldRole)
                ).list();
        for (TimelineMilestone timelineMilestone : timelineMilestoneList) {
            timelineMilestone.setRole(newRole);
        }

        timelineDao.updateInTx(timelineList);
        timelineTextDao.updateInTx(timelineTextList);
        timelinePhotoDao.updateInTx(timelinePhotoList);
        timelinePhotoUrlDao.updateInTx(timelinePhotoUrlList);
        timelineAudioUrlDao.updateInTx(timelineAudioUrlList);
        timelineVideoScreenshotUrlDao.updateInTx(timelineVideoScreenshotUrlList);
        timelineVideoUrlDao.updateInTx(timelineVideoUrlList);
        timelineMilestoneDao.updateInTx(timelineMilestoneList);
    }

    public long queryMessageServerTS(String userID) {
        openReadableDb();
        MessageDao messageDao = daoSession.getMessageDao();
        Message message = messageDao.queryBuilder().where(MessageDao.Properties.UserID.eq(userID)).unique();
        if (message == null) {
            return 0;
        }
        return message.getSyncTS();
    }

    public void updateMessageServerTS(String userID, long serverTS) {
        openWritableDb();
        MessageDao messageDao = daoSession.getMessageDao();
        Message message = messageDao.queryBuilder().where(MessageDao.Properties.UserID.eq(userID)).unique();
        if (message == null) {
            message = new Message();
            message.setUserID(userID);
        }
        message.setSyncTS(serverTS);
        messageDao.insertOrReplace(message);
    }

    public void deleteTimeline(int babyId) {
        openWritableDb();
        TimelineDao timelineDao = daoSession.getTimelineDao();
        List<Timeline> list = timelineDao.queryBuilder().where(TimelineDao.Properties.BabyID.eq(babyId)).list();
        Logger.d("删除了内容长度" + list.size());
        if (list != null && list.size() > 0) {
            timelineDao.deleteInTx(list);
        }

        // 删除缓存本地日记
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> discovers = discoverDao.queryBuilder().where(DiscoverDao.Properties.BabyID.eq(babyId)).list();
        if(discovers != null && discovers.size() > 0) {
            discoverDao.deleteInTx(discovers);
        }
    }

    public void deleteSyncTs(int babyId) {
        openWritableDb();
        TimelineServerTimeDao timelineServerTimeDao = daoSession.getTimelineServerTimeDao();
        TimelineServerTime timelineServerTime = timelineServerTimeDao.queryBuilder().where(TimelineServerTimeDao.Properties.BabyID.eq(babyId)).unique();
        if (timelineServerTime != null) {
            timelineServerTimeDao.delete(timelineServerTime);
        }
    }

    public void deleteLastSyncTs(int babyId) {
        openWritableDb();
        TimelineLastServerTimeDao timelineLastServerTimeDao = daoSession.getTimelineLastServerTimeDao();
        TimelineLastServerTime timelineLastServerTime = timelineLastServerTimeDao.queryBuilder().where(TimelineLastServerTimeDao.Properties.BabyID.eq(babyId)).unique();
        if (timelineLastServerTime != null) {
            timelineLastServerTimeDao.delete(timelineLastServerTime);
        }
    }

    /*日记圈*/

    public void updateDiscoverSyncTime(String userId) {

    }

    public void deleteDiscoverSyncTime(String userId) {

    }

    // 插入或者更新评论
    public void insertOrReplaceDiscoverSaveCommentInTx(ArrayList<DiscoverSaveComment> comments) {
        openWritableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        DiscoverSaveComment[] commentArray = new DiscoverSaveComment[comments.size()];
        for(int i = 0; i < comments.size(); i++) {
            // 判断是否存在，查询条件：from（1代表最新评论，2代表日记评论）和日记的唯一编号
            DiscoverSaveComment comment = commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.Identity.eq(comments.get(i).getIdentity()), DiscoverSaveCommentDao.Properties.From.eq(comments.get(i).getFrom())).unique();
            if(comment != null) {
                comments.get(i).setId(comment.getId());
            }
            commentArray[i] = comments.get(i);
        }
        commentDao.insertOrReplaceInTx(commentArray);
    }

    // 插入或者更新评论
    public void insertOrReplaceDiscoverSaveComment(DiscoverSaveComment comment) {
        openWritableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        DiscoverSaveComment model = commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.Identity.eq(comment.getIdentity())).where(DiscoverSaveCommentDao.Properties.From.eq(comment.getFrom())).unique();
        if(model != null) {
            comment.setId(model.getId());
        }
        commentDao.insertOrReplace(comment);
    }

    // 删除当前登录的用户下所有from为1(最新评论)的评论信息
    public void deleteAllNewComments(String userId) {
        openWritableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        List<DiscoverSaveComment> comments = commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.BelongUserId.eq(userId)).where(DiscoverSaveCommentDao.Properties.From.eq(1)).list();
        commentDao.deleteInTx(comments);

        // 删除评论对应的日记
//        DiscoverDao discoverDao = daoSession.getDiscoverDao();
//        for(DiscoverSaveComment comment : comments) {
//            Discover discover = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(comment.getDiaryID())).unique();
//            discoverDao.delete(discover);
//        }
        // discoverDao.deleteAll();
    }

    // 删除评论
    public void deleteComment(String commentId) {
        openWritableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        List<DiscoverSaveComment> comments = commentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.Identity.eq(commentId)).list();
        commentDao.deleteInTx(comments);
    }

    // 根据当前登录的用户，查询新或旧的评论信息
    public ArrayList<CommentModel> getNewOrOldComments(boolean isNew, String userId) {
        openReadableDb();
        ArrayList<CommentModel> models = new ArrayList<>();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        BabyDao babyDao = daoSession.getBabyDao();
        ArrayList<DiscoverSaveComment> comments = (ArrayList<DiscoverSaveComment>) commentDao.queryBuilder()
                .where(DiscoverSaveCommentDao.Properties.IsNew.eq(isNew))               // 新Or旧评论
                .where(DiscoverSaveCommentDao.Properties.BelongUserId.eq(userId))       // 当前用户的UserID
                .where(DiscoverSaveCommentDao.Properties.From.eq(1))                    // 属于最新评论的信息
                .where(DiscoverSaveCommentDao.Properties.OperationState.eq(1))          // 是非删除的赞或评论
                .orderDesc(DiscoverSaveCommentDao.Properties.CreateTS).list();
        for(int i = 0; i < comments.size(); i++) {
            DiscoverSaveComment comment = comments.get(i);
            // 取消赞，没有日记编号，就不显示了
            if(TextUtils.isEmpty(comment.getDiaryID())) {
                continue;
            }
//            if(isNew) {
//                // 如果是新的评论，在查询时将其状态改为 false
//                comment.setIsNew(false);
//            }
            Discover discover = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(comment.getDiaryID()), DiscoverDao.Properties.DiaryFrom.eq(3)).unique();
//            Baby baby = babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(discover.getBabyID())).unique();
//            if(baby != null) {
//                discover.setDiaryName(baby.getNoteName());
//            }
            models.add(new CommentModel(comment, discover));
        }
        // 更新评论的状态
//        commentDao.updateInTx(comments);
        return models;
    }

    // 查询新评论的条数
    public long getNewCommentCount(String userId) {
        openReadableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        return commentDao.queryBuilder()
                .where(DiscoverSaveCommentDao.Properties.From.eq(1))
                .where(DiscoverSaveCommentDao.Properties.OperationState.eq(1))
                .where(DiscoverSaveCommentDao.Properties.IsNew.eq(true))
                .where(DiscoverSaveCommentDao.Properties.BelongUserId.eq(userId))
                .count();
    }

    // 根据当前登录的用户，查询指定数量的评论信息
    public ArrayList<CommentModel> getComments(int number, long createTs, String userId) {
        openReadableDb();
        ArrayList<CommentModel> models = new ArrayList<>();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        BabyDao babyDao = daoSession.getBabyDao();
        ArrayList<DiscoverSaveComment> comments = (ArrayList<DiscoverSaveComment>) commentDao.queryBuilder()
                // .where(DiscoverSaveCommentDao.Properties.IsNew.eq(isNew))        // 新/旧的评论
                .where(DiscoverSaveCommentDao.Properties.CreateTS.lt(createTs))     // 分页时间戳
                .where(DiscoverSaveCommentDao.Properties.From.eq(1))                // 最新评论信息
                .where(DiscoverSaveCommentDao.Properties.OperationState.eq(1))      // 新增的赞/评论
                .where(DiscoverSaveCommentDao.Properties.BelongUserId.eq(userId))   // 当前用户登录的UserID
                .orderDesc(DiscoverSaveCommentDao.Properties.CreateTS).limit(number).list();
        for(int i = 0; i < comments.size(); i++) {
            DiscoverSaveComment comment = comments.get(i);
            Discover discover = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(comment.getDiaryID()), DiscoverDao.Properties.DiaryFrom.eq(3)).unique();
//            Baby baby = babyDao.queryBuilder().where(BabyDao.Properties.BabyID.eq(discover.getBabyID())).unique();
//            if(baby != null) {
//                discover.setDiaryName(baby.getNoteName());
//            }
            models.add(new CommentModel(comment, discover));
        }
        return models;
    }

    // 更新评论
    public void updateComments(ArrayList<DiscoverSaveComment> comments) {
        openWritableDb();
        DiscoverSaveCommentDao commentDao = daoSession.getDiscoverSaveCommentDao();
        commentDao.updateInTx(comments);
    }

    // 获取单条日记下面所有的赞或者是评论
    public ArrayList<DiscoverSaveComment> getDiscoverAllComments(String diaryId, int commentType) {
        openReadableDb();
        DiscoverSaveCommentDao saveCommentDao = daoSession.getDiscoverSaveCommentDao();
        ArrayList<DiscoverSaveComment> comments = (ArrayList<DiscoverSaveComment>) saveCommentDao.queryBuilder()
                .where(DiscoverSaveCommentDao.Properties.From.eq(2))
                .where(DiscoverSaveCommentDao.Properties.DiaryID.eq(diaryId))
                .where(DiscoverSaveCommentDao.Properties.OperationState.eq(1)) // 前提是没有取消赞或删除评论
                .where(DiscoverSaveCommentDao.Properties.CommentType.eq(commentType))
                .orderAsc(DiscoverSaveCommentDao.Properties.CreateTS).list();
        if (comments == null) {
            comments = new ArrayList<DiscoverSaveComment>();
        }
        return comments;
    }

    // 删除单挑日记下面的所有评论
    public void deleteDiscoverComments(String diaryId) {
        openWritableDb();
        DiscoverSaveCommentDao saveCommentDao = daoSession.getDiscoverSaveCommentDao();
        saveCommentDao.deleteInTx(saveCommentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.DiaryID.eq(diaryId)).where(DiscoverSaveCommentDao.Properties.From.eq(2)).list());
    }

    // 获取离线的待同步的评论
    public List<DiscoverSaveComment> getLocalComments(String userId) {
        openReadableDb();
        DiscoverSaveCommentDao saveCommentDao = daoSession.getDiscoverSaveCommentDao();
        return saveCommentDao.queryBuilder().where(DiscoverSaveCommentDao.Properties.IsLocal.eq(true)).where(DiscoverSaveCommentDao.Properties.UserID.eq(userId)).list();
    }

    // 插入或更新日记
    public void insertOrReplaceDiscover(Discover discover, String[] photos) {
        openWritableDb();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        Discover model = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(discover.getDiaryID()), DiscoverDao.Properties.DiaryFrom.eq(discover.getDiaryFrom())).unique();
        if(model != null) {
            discover.setId(model.getId());
        }
        discoverDao.insertOrReplace(discover);
        // 考虑到服务器图片的缓存策略，只存一次日记的图片地址
        DiscoverPhotoDao photoDao = daoSession.getDiscoverPhotoDao();
        if(photoDao.queryBuilder().where(DiscoverPhotoDao.Properties.DiscoverID.eq(discover.getDiaryID())).count() > 0){
            return;
        }
        if(photos != null && photos.length > 0) {
            for(String photoUrl : photos) {
                DiscoverPhoto photo = new DiscoverPhoto();
                photo.setDiscoverID(discover.getDiaryID());
                photo.setUrl(photoUrl);
                DiscoverPhoto photoModel = photoDao.queryBuilder()
                        .where(DiscoverPhotoDao.Properties.DiscoverID.eq(discover.getDiaryID()))
                        .where(DiscoverPhotoDao.Properties.Url.eq(photoUrl)).unique();
                if(photoModel != null) {
                    photo.setId(photoModel.getId());
                }
                photoDao.insertOrReplace(photo);
            }
        }
    }

    // 查询日记的第一张照片
    public String getDiscoverFirstPhoto(String diaryId) {
        openReadableDb();
        String url = null;
        DiscoverPhotoDao photoDao = daoSession.getDiscoverPhotoDao();
        ArrayList<DiscoverPhoto> photos = (ArrayList<DiscoverPhoto>) photoDao.queryBuilder().where(DiscoverPhotoDao.Properties.DiscoverID.eq(diaryId)).limit(1).list();
        if(photos.size() > 0) {
            url = photos.get(0).getUrl();
        }
        return url;
    }

    // 查询日记的所有照片
    public ArrayList<DiscoverPhoto> getDiscoverPhotos(String diaryId) {
        openReadableDb();
        DiscoverPhotoDao photoDao = daoSession.getDiscoverPhotoDao();
        return (ArrayList<DiscoverPhoto>) photoDao.queryBuilder().where(DiscoverPhotoDao.Properties.DiscoverID.eq(diaryId)).list();
    }

    // 更新日记的音频信息的本地路径
    public void updateDiscoverAudioLocalPath(String url, String diaryId) {
        openWritableDb();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        List<Discover> models = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(diaryId)).list();
        if(models.size() > 0) {
            for(Discover model : models) {
                model.setAudioLocalUrl(url);
            }
            discoverDao.updateInTx(models);
        }
    }

    // 获取单条日记信息
    public Discover getDiscoverByDiaryId(String diaryId, int from) {
        openReadableDb();
        DiscoverDao discoverDao = daoSession.getDiscoverDao();
        Discover discover = discoverDao.queryBuilder().where(DiscoverDao.Properties.DiaryID.eq(diaryId), DiscoverDao.Properties.DiaryFrom.eq(from)).unique();
        return discover;
    }

    /*私有方法*/

    /*Query for readable DB*/
    private void openReadableDb() throws SQLiteException {
        database = mHelper.getReadableDatabase();
        daoMaster = new DaoMaster(database);
        daoSession = daoMaster.newSession();
    }

    /*Query for writable DB*/
    private void openWritableDb() throws SQLiteException {
        database = mHelper.getWritableDatabase();
        daoMaster = new DaoMaster(database);
        daoSession = daoMaster.newSession();
    }


}
